﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace BL.BIZControls
{


    public partial class ModalContainer : ControlContainerBase
    {
        
        public bool UnLoadControlOnClose { get { return ViewState["UnLoadControlOnClose"] != null ? (bool)ViewState["UnLoadControlOnClose"] : true; } set { ViewState["UnLoadControlOnClose"] = value; } }
        public event ModalControlClosing ModalClosing;
        public event ControlLoaded BIZControlLoaded;
        public event CycleError UserControlCycleError;
        public event EventHandler FormScrollStyleChanged;


        private bool _ActivateParent = false;

        #region Styling

        public int Width
        {
            get { return ViewState["width"] != null ? (int)ViewState["width"] : 0; }
            set
            {
                int val = value;

                if (ModalDialog_ww.Value != "" && int.Parse(ModalDialog_ww.Value) < value)
                {
                    val = int.Parse(ModalDialog_ww.Value); 
                }
 
                ViewState["width"] = val; ModalDialog.Style.Remove(HtmlTextWriterStyle.Width);
                ModalDialog.Style.Add(HtmlTextWriterStyle.Width, val.ToString() + "px");
            }
        }
        public int Height
        {
            get { return ViewState["height"] != null ? (int)ViewState["height"] : 0; }
            set
            {

                int val = value;

                if (ModalDialog_wh.Value != "" && int.Parse(ModalDialog_wh.Value) < value)
                {
                    val = int.Parse(ModalDialog_wh.Value);
                }
                
                ViewState["height"] = val; ModalDialog.Style.Remove(HtmlTextWriterStyle.Height);
                ModalDialog.Style.Add(HtmlTextWriterStyle.Height, val.ToString() + "px");
            }
        }


        public void CenterDialog()
        {
            if (ModalDialog_t.Value != "")
            {
                ModalDialog.Style.Remove(HtmlTextWriterStyle.Top);
                ModalDialog.Style.Add(HtmlTextWriterStyle.Top, ModalDialog_t.Value);
            }

            if (ModalDialog_l.Value != "")
            {
                ModalDialog.Style.Remove(HtmlTextWriterStyle.Left);
                ModalDialog.Style.Add(HtmlTextWriterStyle.Left, ModalDialog_l.Value);
            }
        }

        public void SetModalSize(int width, int height)
        {
            ModalDialog.Style.Remove(HtmlTextWriterStyle.Width);
            ModalDialog.Style.Add(HtmlTextWriterStyle.Width, width.ToString() + "px");

            ModalDialog.Style.Remove(HtmlTextWriterStyle.Height);
            ModalDialog.Style.Add(HtmlTextWriterStyle.Height, height.ToString() + "px");
           
            if (ContainedControl.FindControl("formscroll") != null)
            {
                HtmlControl formScroll = (HtmlControl)ContainedControl.FindControl("formscroll");

                bool tabBlock = false;
                bool subNavBlock = false;
                if (ContainedControl is BIZControlBase)
                {
                    tabBlock = ((BIZControlBase)ContainedControl).SetTabSize;
                    subNavBlock = ((BIZControlBase)ContainedControl).SetSubNavSize;    
                }


                int sheight = GetScrollHeight(height, btnGUI.Visible, tabBlock, subNavBlock);
                

                formScroll.Style.Remove(HtmlTextWriterStyle.Height);
                formScroll.Style.Add(HtmlTextWriterStyle.Height, sheight.ToString() + "px");

                formScroll.Style.Remove(HtmlTextWriterStyle.Overflow);
                formScroll.Style.Add(HtmlTextWriterStyle.Overflow, "auto");

                if (ContainedControl is BIZListControl)
                {
                    HtmlControl listScroll = ((BIZListControl)ContainedControl).ListScroll;

                    if (listScroll != null)
                    {
                        int formPartHeight = ((BIZListControl)ContainedControl).FormPartHeight;

                        //Om det finns en pager för listan ska listScroll kortas ytterligare på höjden 
                        //enklast att göra det är att sätta att höjden på formpart är högre.
                        if (((BIZListControl)ContainedControl).PagerSpace)
                            formPartHeight += 59;

                        //ev köra int listHeight =  GetScrollHeight(sheight, btnGUI.Visible, tabBlock);

                        listScroll.Style.Remove(HtmlTextWriterStyle.Height);
                        listScroll.Style.Add(HtmlTextWriterStyle.Height, (sheight - formPartHeight).ToString() + "px");

                        listScroll.Style.Remove(HtmlTextWriterStyle.Overflow);
                        listScroll.Style.Add(HtmlTextWriterStyle.Overflow, "auto");

                       
                    }

                }

                if (FormScrollStyleChanged != null)
                {
                    FormScrollStyleChanged(this, null);
                }
            }
           
        }

        public int GetScrollHeight(int height, bool buttonBlock, bool tabBlock, bool subNavBlock)
        {
            if (Request.Browser.Browser.ToLower().Contains("mozilla") || Request.Browser.Browser.ToLower().Contains("firefox"))
            {
                height = height - 15;
            }


            if (buttonBlock)
            {
                height = height - 115;
            }
            else
            {
                height = height - 70;
            }

            if (tabBlock)
            {
                height = height - 60;
            }

            if (subNavBlock)
            {
                height = height - 45;
            }

           return height;
        }

        public void SetOpenStyle(bool open)
        {
            if (open)
            {
                Container.Style.Clear();
                Container.Style.Remove(HtmlTextWriterStyle.Display);
            }
            else
            {
                Container.Style.Add(HtmlTextWriterStyle.Display, "none");
                if (ContainedControl is IContainedControl)
                {
                    ((IContainedControl)ContainedControl).ControlState = VisibleState.Closed;
                }
                     
            }           
        }

        public void SetStateStyles()
        {
            if (ContainedControl is IContainedControl)
            {
                VisibleState state = ((IContainedControl)ContainedControl).ControlState;

                if (state == VisibleState.Active)
                {
                    ModalDialog.Style.Remove(HtmlTextWriterStyle.ZIndex);
                    ModalDialog.Style.Add(HtmlTextWriterStyle.ZIndex, "102");

                    ModalDialog.Style.Remove(HtmlTextWriterStyle.Overflow);
                    ModalDialog.Style.Add(HtmlTextWriterStyle.Overflow, "auto");
                    ModalPopupBG.Visible = true;
                }
                else if (state == VisibleState.Underlying)
                {
                    ModalDialog.Style.Remove(HtmlTextWriterStyle.ZIndex);
                    ModalDialog.Style.Add(HtmlTextWriterStyle.ZIndex, "101");

                    ModalDialog.Style.Remove(HtmlTextWriterStyle.Overflow);
                    ModalDialog.Style.Add(HtmlTextWriterStyle.Overflow, "hidden");

                    ModalPopupBG.Visible = false;
                }
                else if (state == VisibleState.Closed)
                {

                    ModalPopupBG.Visible = false;
                    ModalDialog.Style.Remove(HtmlTextWriterStyle.Overflow);
                    ModalDialog.Style.Add(HtmlTextWriterStyle.Overflow, "hidden");

                }

            }
        }

#endregion

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            ContainedControlContainer = phControl;
            ButtonsControl = btnGUI;
            btnGUI.ButtonsClick += new ButtonsHandler(btnGUI_ButtonsClick);
        }


        protected override void OnLoad(EventArgs e)
        {
           
            base.OnLoad(e);            

            
        }

        protected override void LoadViewState(object savedState)
        {
            base.LoadViewState(savedState);
            AddControl();
        }

        protected override void Render(HtmlTextWriter writer)
        {
            CenterDialog();
            SetStateStyles();
            litTitle.Text = Title;
            base.Render(writer);
        }

        void btnGUI_ButtonsClick(object sender, ActionType actionType)
        {
            CallButtonEvent(this, actionType);

            if (Page.IsValid)
            {
                if (actionType != ActionType.Save)
                {
                    if (!CancelCommand)
                        ModalClose();
                    CancelCommand = false;
                }
            }
        }

        protected void Close_Click(object sender, EventArgs e)
        {
            CallButtonEvent(this, ActionType.Cancel);

            ModalClose();
        }

        /// <summary>
        /// Remove current control from container.
        /// UnLoadControlOnClose = true == automaticly unload control on closing modal
        /// </summary>
        public void Clear()
        {
            phControl.Controls.Clear();
            ControlPath = null;
            ContainedControl = null;
        }

        public void AddControl(BIZControl typeOfControl)
        {

            ControlPath = GetControlPath(typeOfControl);
            AddControl();
        }



        private void AddControl()
        {
            if (ControlPath != null)
            {
                ContainedControl = null;
                bool open = true;

                if (phControl.Controls.Count == 0)
                {

                    if (Width == 0)
                        Width = 350;
                    if (Height == 0)
                        Height = 450;

                    CheckInsidePopup(this);

                    Control uc = (Control)this.LoadControl(ControlPath);

                    bool cycleError = false;

                    if (CheckInsidePopup(this))
                    {
                        cycleError = CheckCycleError(this, uc);
                    }

                    if (cycleError)
                    {

                        if (UserControlCycleError != null)
                        {
                            UserControlCycleError(this, new EventArgs());
                            open = false;
                        }

                    }
                    else
                    {

                        ContainedControl = uc;

                        if (ContainedControl is IContainedControl)
                        {
                            ((IContainedControl)ContainedControl).ContainerControl = this;

                            if (((IContainedControl)ContainedControl).ControlState == VisibleState.Active) 
                            SetModalHirSize(this.Parent, Width, Height);
                        }
                        phControl.Controls.Add(ContainedControl);
                        btnGUI.SetValGroupPrefix(ValGroupPrefix);


                        //Flyttat denna till IF IContainedControl ovan 
                        //så man bara gör det för den kontroll som är aktiv
                        //annars görs detta flera gånger och även på de med state closed
                        //vilket verkar bli fel
                        //SetModalHirSize(this.Parent, Width, Height);
                    }
                }
                else
                {
                    ContainedControl = phControl.Controls[0];
                }




                if (ContainedControl != null)
                {

                    if (BIZControlLoaded != null)
                    {
                        BIZControlLoaded(this, new EventArgs());
                    }

                }
                else
                {
                    open = false;
                }

                if (ViewState["display"] == null || ViewState["display"].ToString() == "none")
                {
                    SetOpenStyle(false);
                    ViewState["display"] = "none";
                    ResetParentModalHirSize(this.Parent);
                }
                else
                {
                    if (open)
                    {
                        ModalOpen();

                    }
                    else
                    {
                        ModalClose(true);
                    }
                }
            }
            else
            {
                SetOpenStyle(false);
                ViewState["display"] = "none";  
            }

        }

        public void ModalOpen()
        {
            SetOpenStyle(true);
            ViewState["display"] = "";

            if (ContainedControl is IContainedControl)
            {
                ((IContainedControl)ContainedControl).ControlState = VisibleState.Active;
            }

            SetModalSize(Width, Height);
            SetModalHirSize(this.Parent, Width, Height);
        }

        public void ModalClose()
        {
            ModalClose(UnLoadControlOnClose);
        }

        
        /// <summary>
        /// Stänger ner Popupcontrollen
        /// </summary>
        /// <param name="unloadControl">Här kan man välja om kontrollen ska finnas kvar i sidan (fast inte visas) eller om den ska plockas bort (dvs då går det inte att anropa kontrollen längre) </param>
        public void ModalClose(bool unloadControl)
        {
            SetOpenStyle(false);
            ViewState["display"] = "none";

            if (ModalClosing != null)
            {
                ModalClosing(this, new EventArgs());
            }


            _ActivateParent = true;
            ResetParentModalHirSize(this.Parent);

            if (unloadControl)
            {
                Clear();
            }
        
        }


        /// <summary>
        /// Ändrar alla andra modala dialoger till samma storlek så man inte kan se dem under aktiv dialog
        /// </summary>
        /// <param name="dialog"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        protected void SetModalHirSize(Control container, int width, int height)
        {
            if (container != null && container != Page)
            {

                if (container is ModalContainer)
                {
                    if(((ModalContainer)container).ContainedControl is IContainedControl)
                    {
                        ((IContainedControl)((ModalContainer)container).ContainedControl).ControlState = VisibleState.Underlying;
                    }

                    ((ModalContainer)container).SetModalSize(width, height);

                }

                SetModalHirSize(container.Parent, width, height);

            }
        }

        /// <summary>
        /// Ändrar närmaste dialog i kedjan av öppnade dialoger till ursprunglig storlek 
        /// </summary>
        /// <param name="dialog"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        protected void ResetParentModalHirSize(Control container)
        {
            if (container != null && container != Page)
            {

                if (container is ModalContainer)
                {
                    int width = ((ModalContainer)container).Width;
                    int height = ((ModalContainer)container).Height;
                    ((ModalContainer)container).SetModalSize(width, height);

                    if (((ModalContainer)container).ContainedControl is IContainedControl && _ActivateParent)
                    {
                        ((IContainedControl)((ModalContainer)container).ContainedControl).ControlState = VisibleState.Active;
                        _ActivateParent = false;
                    }


                    SetModalHirSize(container.Parent, width, height);
                }
                else
                {
                    ResetParentModalHirSize(container.Parent);
                }

            }
        }


        /// <summary>
        /// Kolla om den här popuppen är i en annan för då behöver lite style ändras
        /// </summary>
        /// <param name="C"></param>
        /// <returns></returns>
        private bool CheckInsidePopup(Control C)
        {
            if (C.Parent != null)
            {
                if (C.Parent is ModalContainer)
                {
                    return true;
                }
                else
                {
                    return CheckInsidePopup(C.Parent);
                }
            }

            return false;
        }

        /// <summary>
        /// Kolla så att man inte öppnar en likadan kontroll i sig själv eller att man öppnar samma popup igen om man har flera öppna
        /// (det blir en evighetsloop om det skulle hända)
        /// </summary>
        /// <param name="C"></param>
        /// <param name="uc"></param>
        /// <returns></returns>
        private bool CheckCycleError(Control C, Control uc)
        {
            if (C.Parent != null)
            {
                if (C.Parent.GetType() == uc.GetType())
                {
                    return true;
                }
                else
                {
                    return CheckCycleError(C.Parent, uc);
                }
            }

            return false;
        }

        public bool CanAddPopupControl(Control uc)
        {
            if (CheckCycleError(this, uc))
                return false;
          
            return true;
        }

        public bool CanAddPopupControl(BIZControl typeOfControl)
        {

            UserControl uc = (UserControl)this.LoadControl(GetControlPath(typeOfControl));

            if (CheckCycleError(this, uc))
                return false;

            return true;
        }


        public void AddDefaultEditNew(BIZControl typeOfControl)
        {

            ControlPath = GetControlPath(typeOfControl);
            AddControl();

            ((IBIZControlDefaultMethods)ContainedControl).DefaultEditNew();
            ModalOpen();

        }
        public void AddDefaultEditNew(BIZControl typeOfControl, Guid Id, string editByType)
        {

            ControlPath = GetControlPath(typeOfControl);
            AddControl();

            ((IBIZControlDefaultMethods)ContainedControl).DefaultEditNew(Id, editByType);
            ModalOpen();

        }
        public void AddDefaultEditLoad(BIZControl typeOfControl, Guid Id)
        {

            ControlPath = GetControlPath(typeOfControl);
            AddControl();

            ((IBIZControlDefaultMethods)ContainedControl).DefaultEditLoad(Id);
            ModalOpen();
        }
        public void AddDefaultListLoad(BIZControl typeOfControl)
        {

            AddDefaultListLoad(typeOfControl,false);

        }
        public void AddDefaultListLoad(BIZControl typeOfControl, Guid Id, string loadByType)
        {

            AddDefaultListLoad(typeOfControl,Id,loadByType,false);
        }
        public void AddDefaultListLoad(BIZControl typeOfControl, bool pickerControl)
        {

            ControlPath = GetControlPath(typeOfControl);
            AddControl();

            ContainedListControl.PickerControl = pickerControl;

            ((IBIZControlDefaultMethods)ContainedControl).DefaultListLoad();
            ModalOpen();

        }
        public void AddDefaultListLoad(BIZControl typeOfControl, Guid Id, string loadByType, bool pickerControl)
        {

            ControlPath = GetControlPath(typeOfControl);
            AddControl();

            ContainedListControl.PickerControl = pickerControl;

            ((IBIZControlDefaultMethods)ContainedControl).DefaultListLoad(Id, loadByType);
            ModalOpen();

        }

    }
}